/*
 * ＡＤＰＣＭファイル（.adp）を ホストマシンから
 * ロードし、ＫＲＡＭにセットする
 * 大きなＡＤＰＣＭファイルを読み込ませると正常に動作しない場合があります
 */
#include <system.h>
#include <v93.h>
#include <common.h>
#include <king.h>
#include <king_ks.h>
#include <soundbox.h>
#include <adp.h>
#include "vardecl.h"
#include "adpcm.h"

/* adpファイルのヘッダーのサイズ（変更しないでください） */
#define PCM_HEADERSIZE  sizeof(ADPCMHEADER)
/* フォーマット確認用ＩＤ */
#define fourch(c0, c1, c2, c3) ( \
  (long)(char)(c0) \
  | ((long)(char)(c1)<<8) \
  | ((long)(char)(c2)<<16) \
  | ((long)(char)(c3)<<24) )
#define ID_RIFF fourch('R','I','F','F')
#define FM_WAVE fourch('W','A','V','E')
#define ID_fmt  fourch('f','m','t',' ')

/*
 #undef __DEBUG__ を #define  __DEBUG__ にすると、ＡＤＰＣＭロード時に
   ファイル名を表示し、ロード終了時に実際に鳴らすようになります。 
 */
#undef __DEBUG__

/*
 * 読み込むファイル名
 * サンプルデータを adpファイルに変換して、下の配列に
 * ファイル名を書き込むと、その音で効果音がなります。
 * ここで組み込んだファイルと同じ順番で ADPCM.Hに
 * 名称を書いておきます。
 */
unsigned char *FileName[]={
  "dat/adpcm/hit3.adp",       /* 車がぶつかった音 */
  "dat/adpcm/slip3.adp",      /* ぶつかった後にすべる音 */
  "dat/adpcm/bomb.adp",       /* 現在未使用 */
  "dat/adpcm/monster1.adp",   /* ボスがやられた音 */
  "dat/adpcm/m_bomb3.adp",    /* ボスのコアがやられた音 */
  "dat/adpcm/pause.adp",      /* ポーズ音 */
  "dat/adpcm/start.adp",      /* ゲームスタート！ */
  "dat/adpcm/youwon.adp",     /* ユーウォン！ */
  "dat/adpcm/youlost.adp",    /* ユーロスト！ */
  "dat/adpcm/over4.adp"       /* ゲームオーバー */
};

/*
========================================
  データをＫＲＡＭにセット
  引き数：なし
  戻り値：なし
========================================
 */
void
APLSetData (void)
{
  unsigned short uKb;
  int           i,offset;
  int           fh;
  unsigned char cBuf;
  long          filelength;
  ADPCMHEADER   aPcmHead;

#ifdef __DEBUG__
  AdpcmVolume(CHANNEL_1,MIN_PCM_VOLUME,MIN_PCM_VOLUME);
  AdpcmVolume(CHANNEL_2,MIN_PCM_VOLUME,MIN_PCM_VOLUME);
  AdpcmInit();
  AdpcmVolume(CHANNEL_1,MAX_PCM_VOLUME,MAX_PCM_VOLUME);
#else
  pio_putstr("ADPCM Loading");
#endif

  /* ＰＣＭの個数分ループ */
  uKb  = 0;
  for( i = 0; i < MAX_PCM_NUMBER; i++){

#ifdef __DEBUG__
    pio_putstr("\nLoading:");
    pio_putstr(FileName[i]);
#else
    pio_putstr(".");
#endif
    /* ファイルを開く */
    if((fh = pio_fopen(FileName[i],"rb")) == -1){
      pio_putstr(FileName[i]);
      pio_putstr(" が開けません。\n");
      _exit();
    }
    offset = 0;
    /* ヘッダー部読み込み */
    if(pio_fread(fh,PCM_HEADERSIZE, &aPcmHead) != PCM_HEADERSIZE){
      /* 読み込みに失敗したらエラー表示 */
      pio_putstr(FileName[i]);
      pio_putstr(" の読み込みに失敗しました。\n");
      _exit();
    }
    /* 簡易的にヘッダーを調査する */
    if (aPcmHead.fileid != ID_RIFF || aPcmHead.format_type != FM_WAVE || 
        aPcmHead.info.fileid != ID_fmt) {
        /* 違うヘッダーだったらエラー表示 */
        pio_putstr(FileName[i]);
        pio_putstr(" のヘッダーが正しくないか未対応のフォーマットです。\n");
        _exit();
    }
    /* ファイルを最後まで読み込み */
    pio_fseek(fh,0L,0);
    filelength = aPcmHead.info.datasize + PCM_HEADERSIZE;
    /* ファイルの読み込み */
    if(pio_fread(fh, filelength, (char *)filereadbuf) != filelength){
      pio_putstr(FileName[i]);
      pio_putstr(" の読み込みに失敗しました。\n");
      _exit();
    }
    /* 読み込んだデータのＫＲＡＭへのセット */
    uKb += AdpcmDataSet(&pInfo[i],filereadbuf,uKb,PCM_NORMAL);
    /* ファイルを閉じる */
    pio_fclose(fh);

#ifdef __DEBUG__
    /* ＡＤＰＣＭを鳴らす */
    AdpcmPlay(CHANNEL_1,&pInfo[i]);
    AdpcmWait(CHANNEL_1);
#endif
  }
#ifdef __DEBUG__
  /* 鳴り終わるまで待つ */
  AdpcmWait(CHANNEL_1);
  AdpcmVolume(CHANNEL_1,MIN_PCM_VOLUME,MIN_PCM_VOLUME);
  AdpcmVolume(CHANNEL_2,MIN_PCM_VOLUME,MIN_PCM_VOLUME);
  VSyncWait();
#endif
  pio_putstr("\n");
}
